<script setup>
import maskCanvas from './maskCanvas.vue';
import { ref, watch, nextTick, getCurrentInstance } from 'vue';

const props = defineProps({
  imageFileUrl: String,
  size: String
})



const instance = getCurrentInstance()


const queryParams = ref({
  topOffset: 0,
  bottomOffset: 0,
  leftOffset: 0,
  rightOffset: 0,
})
// 百分比信息
const percent = ref({
  topScale: 0,
  bottomScale: 0,
  leftScale: 0,
  rightScale: 0,
})
// 像素信息
const pixelInfo = ref({
  topOffset: 0,
  bottomOffset: 0,
  leftOffset: 0,
  rightOffset: 0,
})

// 父盒子尺寸信息
const contentDom = ref({})
// 边框盒子尺寸信息
const borderRect = ref({})
// 原图尺寸信息
const oldImgRect = ref({})
// 图片尺寸信息
const imgRect = ref({})
// 缩放比例
const scaleRatio = ref(1)

const borderShow = ref(false)

const maskCanvasRef = ref(null)





watch(() => props.imageFileUrl, (val, oldVal) => {
  getDom().then(() => {
    calculatePicAspectRatio(val)

    setTimeout(() => {
      if (oldVal && props.size !== '原图') {
        const data = getAspectRatioFn({
          width: imgRect.value.width,
          height: imgRect.value.height,
          ratio: props.size
        })
        queryParams.value = Object.assign(queryParams.value, data?.periphery)
      } else {
        queryParams.value = Object.assign(queryParams.value, {
          topOffset: 0,
          bottomOffset: 0,
          leftOffset: 0,
          rightOffset: 0
        })
      }
    }, 0)
  })
}, { immediate: true, deep: true })


watch(() => props.size, (val) => {
  if (val === '原图') {
    queryParams.value = Object.assign(queryParams.value, {
      topOffset: 0,
      bottomOffset: 0,
      leftOffset: 0,
      rightOffset: 0
    })
  } else {
    const data = getAspectRatioFn({
      width: imgRect.value.width,
      height: imgRect.value.height,
      ratio: val
    })
    queryParams.value = Object.assign(queryParams.value, data?.periphery)
  }
}, { immediate: true, deep: true })




function drawImage() {
  return new Promise((resolve) => {
    nextTick(() => {
      resolve(maskCanvasRef.value.loadDrawImage())
    })
  })
}



/**
 * 根据 queryParams 的像素值计算图片距离矩形的百分比尺寸信息
 * 需要将缩放后的位置信息还原为缩放前的位置信息
 */
function calculatePercentages() {
  if (!imgRect.value.width || !imgRect.value.height || !scaleRatio.value) return;

  // 还原为缩放前的位置信息
  const originalTopOffset = queryParams.value.topOffset / scaleRatio.value;
  const originalBottomOffset = queryParams.value.bottomOffset / scaleRatio.value;
  const originalLeftOffset = queryParams.value.leftOffset / scaleRatio.value;
  const originalRightOffset = queryParams.value.rightOffset / scaleRatio.value;

  // 计算百分比
  percent.value.topScale = Math.ceil((originalTopOffset / oldImgRect.value.height) * 100) / 100;
  percent.value.bottomScale = Math.ceil((originalBottomOffset / oldImgRect.value.height) * 100) / 100;
  percent.value.leftScale = Math.ceil((originalLeftOffset / oldImgRect.value.width) * 100) / 100;
  percent.value.rightScale = Math.ceil((originalRightOffset / oldImgRect.value.width) * 100) / 100;
}

/**
 * 将缩放后的位置信息还原为缩放前的像素位置信息
 */
function restoreOriginalOffsets() {
  if (!scaleRatio.value) return;
  pixelInfo.value.topOffset = queryParams.value.topOffset / scaleRatio.value;
  pixelInfo.value.bottomOffset = queryParams.value.bottomOffset / scaleRatio.value;
  pixelInfo.value.leftOffset = queryParams.value.leftOffset / scaleRatio.value;
  pixelInfo.value.rightOffset = queryParams.value.rightOffset / scaleRatio.value;
}

// 监听 queryParams 的变化，自动更新百分比信息
watch(queryParams, () => {
  restoreOriginalOffsets()
  calculatePercentages();
}, { deep: true });



// 顶部点击
function topTouchStartFn(e) {
  borderRect.value.top = e.touches[0].clientY;
}
// 顶部拖动事件
async function topTouchMoveFn(e) {
  if (props.size !== '原图') return;
  let top = borderRect.value.top - e.touches[0].clientY;
  queryParams.value.topOffset += top / 4;

  let min = borderRect.value.height + queryParams.value.topOffset;
  let max = borderRect.value.height + queryParams.value.topOffset + queryParams.value.bottomOffset;

  if (min < imgRect.value.height) {
    return (queryParams.value.topOffset = 0);
  } else if (max > imgRect.value.height * 2) {
    return (queryParams.value.topOffset =
      imgRect.value.height * 2 - borderRect.value.height - queryParams.value.bottomOffset);
  }
}

// 右侧点击
function rightTouchStartFn(e) {
  borderRect.value.right = e.touches[0].clientX;
}
// 右侧拖动事件
async function rightTouchMoveFn(e) {
  if (props.size !== '原图') return;
  let right = e.touches[0].clientX - borderRect.value.right;
  queryParams.value.rightOffset += right / 4;

  let min = borderRect.value.width + queryParams.value.rightOffset;
  let max = borderRect.value.width + queryParams.value.rightOffset + queryParams.value.leftOffset;

  if (min < imgRect.value.width) {
    return (queryParams.value.rightOffset = 0);
  } else if (max > imgRect.value.width * 2) {
    return (queryParams.value.rightOffset =
      imgRect.value.width * 2 - borderRect.value.width - queryParams.value.leftOffset);
  }
}

// 底部点击
function bottomTouchStartFn(e) {
  borderRect.value.bottom = e.touches[0].clientY;
}
// 底部拖动事件
async function bottomTouchMoveFn(e) {
  if (props.size !== '原图') return;
  let bottom = e.touches[0].clientY - borderRect.value.bottom;
  queryParams.value.bottomOffset += bottom / 4;

  let min = borderRect.value.height + queryParams.value.bottomOffset;
  let max = borderRect.value.height + queryParams.value.bottomOffset + queryParams.value.topOffset;

  if (min < imgRect.value.height) {
    return (queryParams.value.bottomOffset = 0);
  } else if (max > imgRect.value.height * 2) {
    return (queryParams.value.bottomOffset =
      imgRect.value.height * 2 - borderRect.value.height - queryParams.value.topOffset);
  }
}

// 左侧点击
function leftTouchStartFn(e) {
  borderRect.value.left = e.touches[0].clientX;
}
// 左侧拖动事件
async function leftTouchMoveFn(e) {
  if (props.size !== '原图') return;
  let left = borderRect.value.left - e.touches[0].clientX;
  queryParams.value.leftOffset += left / 4;

  let min = borderRect.value.width + queryParams.value.leftOffset;
  let max = borderRect.value.width + queryParams.value.leftOffset + queryParams.value.rightOffset;

  if (min < imgRect.value.width) {
    return (queryParams.value.leftOffset = 0);
  } else if (max > imgRect.value.width * 2) {
    return (queryParams.value.leftOffset =
      imgRect.value.width * 2 - borderRect.value.width - queryParams.value.rightOffset);
  }
}




/**
 * 计算图片宽高比进行缩放
 * @param {Object} val - 参数对象
 * @param {number} val.width - 图片宽度
 * @param {number} val.height - 图片高度
 * @param {string} val.ratio - 宽高比（如 "3:4"）
 * @returns {Object} - 包含四周偏移量的对象
 */
function getAspectRatioFn({ width, height, ratio }) {
  const [ratioWidth, ratioHeight] = ratio.split(':').map(Number); // 解析宽高比
  const aspectRatio = (ratioWidth / ratioHeight).toFixed(2); // 目标宽高比
  const imgAspectRatio = (width / height).toFixed(2); // 图片宽高比
  const periphery = { topOffset: 0, bottomOffset: 0, leftOffset: 0, rightOffset: 0 };

  // 根据宽高比计算偏移量
  if (imgAspectRatio > aspectRatio) {
    const scaledHeight = (width / ratioWidth) * ratioHeight;
    periphery.topOffset = periphery.bottomOffset = (scaledHeight - height) / 2;
  } else if (imgAspectRatio < aspectRatio) {
    const scaledWidth = (height / ratioHeight) * ratioWidth;
    periphery.leftOffset = periphery.rightOffset = (scaledWidth - width) / 2;
  } else {
    const offset = (Math.max(width, height) * 0.25) / 2;
    periphery.topOffset = periphery.bottomOffset = offset;
    periphery.leftOffset = periphery.rightOffset = offset;
  }

  return { periphery };
}



// 计算图片宽高比及外部边框盒子的宽高
async function calculatePicAspectRatio(path) {
  const { width, height } = await uni.getImageInfo({ src: path })

  const widthRatio = contentDom.value.width / width;
  const heightRatio = contentDom.value.height / height;
  scaleRatio.value = Math.min(widthRatio, heightRatio);

  // 计算缩放后的图片宽度和高度
  const scaledWidth = width * scaleRatio.value;
  const scaledHeight = height * scaleRatio.value;

  // 原图尺寸
  oldImgRect.value = {
    width,
    height,
  }

  // 绘制尺寸
  imgRect.value = {
    width: scaledWidth,
    height: scaledHeight,
  }
  borderRect.value = {
    width: scaledWidth,
    height: scaledHeight,
  }
}



function getDom() {
  return new Promise((resolve) => {
    nextTick(() => {
      uni.createSelectorQuery().in(instance).select('.libertyExpansion').boundingClientRect(rect => {
        contentDom.value = rect
        resolve(rect)
      }).exec()
    })
  })
}

function imgLoad() {
  setTimeout(() => {
    borderShow.value = true
  }, 300)
}


defineExpose({
  percent,
  pixelInfo,
  drawImage
})

</script>

<template>
  <div class='libertyExpansion'>
    <movable-area class="movable_area" scale-area>
      <movable-view class="movable_view" direction="all" scale :scale-min="0.5" :scale-max="1" :scale-value="1">
        <div class="content_box">
          <div class="border_box" :class="{ borderActive: size !== '原图' }" :style="{
            width: borderRect.width + 'rpx', height: borderRect.height + 'rpx',
            paddingTop: queryParams.topOffset + 'rpx', paddingBottom: queryParams.bottomOffset + 'rpx',
            paddingLeft: queryParams.leftOffset + 'rpx', paddingRight: queryParams.rightOffset + 'rpx'
          }">

            <div class="top" @touchstart="topTouchStartFn" @touchmove.stop="topTouchMoveFn"
              v-if="size === '原图' && borderShow">
            </div>
            <div class="right" @touchstart="rightTouchStartFn" @touchmove.stop="rightTouchMoveFn"
              v-if="size === '原图' && borderShow"></div>
            <div class="bottom" @touchstart="bottomTouchStartFn" @touchmove.stop="bottomTouchMoveFn"
              v-if="size === '原图' && borderShow"></div>
            <div class="left" @touchstart="leftTouchStartFn" @touchmove.stop="leftTouchMoveFn"
              v-if="size === '原图' && borderShow">
            </div>

            <div class="img_box" :style="{
              width: imgRect.width + 'rpx',
              height: imgRect.height + 'rpx'
            }">
              <img :src="imageFileUrl" class="imgSty" mode="aspectFill" @load="imgLoad">
            </div>
          </div>


        </div>

      </movable-view>
    </movable-area>
  </div>
  <!-- <div class="maskCanvas_box">
    <maskCanvas ref="maskCanvasRef" :imageFileUrl="imageFileUrl" :width="imgRect.width" :height="imgRect.height"
      :options="queryParams" :oldImgRect="oldImgRect" :pixelInfo="pixelInfo">
    </maskCanvas>
  </div> -->
</template>

<style lang='scss' scoped>
.libertyExpansion {
  position: relative;
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;

  .movable_area {
    width: 100%;
    height: 100%;

    .movable_view {
      width: 100%;
      height: 100%;

      .content_box {
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
      }

      .border_box {
        border: 6rpx solid var(--a-main-color);
        background: url(http://devai.20ai30.com/upload/2024/06/23/file_20240623151030A016.png);
        background-size: 25rpx 25rpx;
        position: relative;

        &.borderActive {
          transition: all 0.3s;
        }

        .img_box {
          display: flex;
          flex-direction: column;
          align-items: center;
          justify-content: center;
          max-width: 100%;
          max-height: 100%;

          .imgSty {
            display: block;
            width: 100%;
            height: 100%;
          }
        }
      }
    }
  }
}

.top {
  position: absolute;
  top: -10rpx;
  left: 50%;
  transform: translate(-50%);
  width: 80rpx;
  height: 15rpx;
  background: #FFFFFF;
  border-radius: 5rpx;
  z-index: 500;

  &::after {
    content: '';
    position: absolute;
    top: 0;
    left: 50%;
    width: 400rpx;
    transform: translate(-50%, -50%);
    height: 200rpx;
  }
}

.right {
  position: absolute;
  top: 50%;
  right: -10rpx;
  transform: translate(0, -50%);
  width: 15rpx;
  height: 80rpx;
  background: #FFFFFF;
  border-radius: 5rpx;
  z-index: 500;

  &::after {
    content: '';
    position: absolute;
    top: 50%;
    left: 0;
    height: 400rpx;
    transform: translate(-50%, -50%);
    width: 200rpx;
  }
}

.bottom {
  position: absolute;
  bottom: -10rpx;
  left: 50%;
  transform: translate(-50%);
  width: 80rpx;
  height: 15rpx;
  background: #FFFFFF;
  border-radius: 5rpx;
  z-index: 500;

  &::after {
    content: '';
    position: absolute;
    top: 0;
    left: 50%;
    width: 400rpx;
    transform: translate(-50%, -50%);
    height: 200rpx;
  }

}

.left {
  position: absolute;
  top: 50%;
  left: -15rpx;
  transform: translate(0, -50%);
  width: 15rpx;
  height: 80rpx;
  background: #FFFFFF;
  border-radius: 5rpx;
  z-index: 500;

  &::after {
    content: '';
    position: absolute;
    top: 50%;
    left: 0;
    height: 400rpx;
    transform: translate(-50%, -50%);
    width: 200rpx;
  }
}



.maskCanvas_box {
  position: fixed;
  left: 200%;
  top: 0;
  width: 100%;
  height: 100%;
}
</style>